# frozen_string_literal: true

require('all')

class HistoryTest < Test::Unit::TestCase
  BOARD_1_1 = [
    %w[a a c],
    %w[a a c],
    %w[i h -]
  ].freeze

  BOARD_1_2 = [
    %w[a a d],
    %w[a a d],
    %w[g j -]
  ].freeze

  BOARD_2 = [
    %w[a a j],
    %w[a a d],
    %w[b b d]
  ].freeze

  def setup
    BoardHistory.instance.clear
  end

  def test_equiv_codes
    assert_equal('00', Equivalence.instance.equiv_codes['-'])
    assert_equal('11', Equivalence.instance.equiv_codes['g'])
    assert_equal('12', Equivalence.instance.equiv_codes['c'])
    assert_equal('21', Equivalence.instance.equiv_codes['b'])
    assert_equal('22', Equivalence.instance.equiv_codes['a'])
  end

  def test_equiv_boards
    assert(Board.new(BOARD_1_1).equiv?(Board.new(BOARD_1_2)))
  end

  def test_base
    assert_equal(
      Equivalence.instance.mapping(Board.new(BOARD_1_1)),
      Equivalence.instance.mapping(Board.new(BOARD_1_2))
    )
  end

  def test_same_seen_depth
    BoardHistory.instance.saw_at_depth(Board.new(BOARD_2), 10)
    assert_equal(10, BoardHistory.instance.equiv_seen_depth(Board.new(BOARD_2)))
  end

  def test_equiv_seen_depth
    BoardHistory.instance.saw_at_depth(Board.new(BOARD_1_1), 7)
    assert_equal(7, BoardHistory.instance.equiv_seen_depth(Board.new(BOARD_1_2)))

    BoardHistory.instance.saw_at_depth(Board.new(BOARD_1_2), 3)
    assert_equal(3, BoardHistory.instance.equiv_seen_depth(Board.new(BOARD_1_1)))
  end

  def test_seen_equiv_at_or_deeper
    BoardHistory.instance.saw_at_depth(Board.new(BOARD_1_1), 9)
    BoardHistory.instance.saw_at_depth(Board.new(BOARD_1_2), 7)

    refute(
      BoardHistory.instance.seen_equiv_at_or_deeper?(Board.new(BOARD_2), nil)
    )

    refute(
      BoardHistory.instance.seen_equiv_at_or_deeper?(Board.new(BOARD_2), 5)
    )

    refute(
      BoardHistory.instance.seen_equiv_at_or_deeper?(Board.new(BOARD_1_1), nil)
    )

    refute(
      BoardHistory.instance.seen_equiv_at_or_deeper?(Board.new(BOARD_1_1), 6)
    )

    assert(
      BoardHistory.instance.seen_equiv_at_or_deeper?(Board.new(BOARD_1_1), 7)
    )

    assert(
      BoardHistory.instance.seen_equiv_at_or_deeper?(Board.new(BOARD_1_1), 8)
    )
  end

  def test_symmetric_equivalence
    assert(
      Board.new(BOARD_2).equiv?(Board.new(BOARD_2).flip_h)
    )
  end
end
